package com.hailiao.devicebasicsdkdemo

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.MutableLiveData
import com.clj.fastble.data.BleDevice
import com.google.android.material.snackbar.Snackbar
import com.hailiao.devicebasicsdkdemo.databinding.ActivityMainBinding
import com.hailiao.devicebasicsdkdemo.utils.showSnackBar
import com.hailiao.hlblelib.HLBleManager
import com.hailiao.hlblelib.bean.CheckDeviceSelfResult
import com.hailiao.hlblelib.bean.DeviceLocationReportInfo
import kotlinx.coroutines.*

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    /** 已连接蓝牙设备 */
    val connectedBleDeviceLive: MutableLiveData<BleDevice?> = MutableLiveData(null)

    /** 设备心跳工作 */
    private var heartbeatJob: Job = Job()

    /** 设备自检信息，也是心跳回复，里面包含设备卡号和设备电量等信息 */
    val deviceCheckSelfInfoLive: MutableLiveData<CheckDeviceSelfResult?> = MutableLiveData(null)

    /** 检查设备需要等待时间的工作 */
    private var checkWaitTimeJob: Job = Job()

    /** 设备发送状态信息，里面包含设备需要等待多久才能下一次发送短报文的时间、中心卡号也就是目标卡号信息 */
    val deviceSendMessageInfoLive: MutableLiveData<DeviceLocationReportInfo?> = MutableLiveData(null)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        // 监听连接设备
        HLBleManager.instance(this.application).connectedDeviceListLive.observe(this@MainActivity, { list ->
            if (connectedBleDeviceLive.value == null) return@observe
            if (list.find { it.mac == connectedBleDeviceLive.value!!.mac } == null) {
                // 没有找到设备，设备已经断开连接
                connectedBleDeviceLive.postValue(null)
            }
        })
        // 启动心跳
        startHeartbeat()
        // 检查等待时间
        startCheckWaitJob()
    }

    /**
     * 显示提示消息
     * @param msg String 消息
     * @param duration Int 显示时间
     */
    fun showSnackBar(msg: String, duration: Int = Snackbar.LENGTH_LONG) {
        binding.root.showSnackBar(msg, duration)
    }

    /**
     * 启动心跳
     */
    private fun startHeartbeat() {
        // 切到子线程去循环心跳
        heartbeatJob = GlobalScope.launch(Dispatchers.IO) {
            while (!isFinishing) {
                // 页面还没有想要关闭的情况下
                when {
                    connectedBleDeviceLive.value == null -> {
                        // 还没连接到设备
                        delay(100)
                    }
                    else -> {
                        // 发送设备自检指令，也是设备心跳
                        val result = HLBleManager.instance(this@MainActivity.application).deviceGetWorker.checkDeviceSelf()
                        deviceCheckSelfInfoLive.postValue(result)
                        // 每隔三秒钟去自检一次
                        delay(3000)
                    }
                }
            }
        }
    }

    /**
     * 检查等待时间
     */
    private fun startCheckWaitJob() {
        checkWaitTimeJob = GlobalScope.launch(Dispatchers.IO) {
            while (!isFinishing) {
                // 页面还没有想要关闭的情况下
                val service = HLBleManager.instance(this@MainActivity.application)
                val info = deviceSendMessageInfoLive.value
                when {
                    connectedBleDeviceLive.value == null -> {
                        // 还没连接到设备
                        delay(100)
                    }
                    info == null || info.waitTimeSecond >= 60 || info.waitTimeSecond < 0 -> {
                        // 还没有检查过等待时间，请求一次等待时间
                        // 刚发送完指令，检查等待时间
                        // 刚设置完卡号，将waitTimeSecond设成-1，请求一次中心卡号
                        val result = service.locationWorker.getDeviceLocationReportInfo()
                        deviceSendMessageInfoLive.postValue(result)
                    }
                    info.waitTimeSecond > 0 -> {
                        info.waitTimeSecond --
                        deviceSendMessageInfoLive.postValue(info)
                        delay(1000)
                    }
                    else -> {
                        delay(1000)
                    }
                }
            }
        }
    }
}